Expand description
Lightweight and flexible command line argument parser with derive and combinatoric style API
§Quick links
- Introduction - features, design goals, restrictions
- Tutorials - practical learning oriented information and
examples to get you started
- Types of arguments - common types of line options and conventions (optional)
- Combinatoric API - Parse arguments without using proc macros
- Derive API - Create a parser by defining a structure
- How-to and guides - assumes familiarity with the basics and explains how to concrete tasks
- Explanations - theoretical information about abstractions used by the library, oriented for understanding
- FAQ - questions from library users
§A quick start
Add bpaf
, optionally with derive enabled
$ cargo add bpaf -F derive,dull_color
Use either derive or combinatoric API and try running it
Combinatoric example
use bpaf::*;
#[derive(Debug, Clone)]
pub struct Options {
message: String,
}
pub fn options() -> OptionParser<Options> {
let message = positional("MESSAGE").help("Message to print in a big friendly letters");
construct!(Options { message }).to_options()
}
fn main() {
println!("{:?}", options().run())
}
Derive example
use bpaf::*;
#[derive(Debug, Clone, Bpaf)]
#[bpaf(options)]
pub struct Options {
/// Message to print in a big friendly letters
#[bpaf(positional("MESSAGE"))]
message: String,
}
fn main() {
println!("{:?}", options().run())
}
Output
With everything in place users should be able to pass their arguments
Options { message: "Hello world" }
As well as read the help message generated by the library
Usage: app MESSAGE
- MESSAGE
- Message to print in a big friendly letters
- -h, --help
- Prints help information
§Consuming items - making Parser
bpaf
allows you to describe the parsers using a mix of two APIs: combinatoric and derive.
Both APIs can achieve the same results, you can use one that better suits your needs. You can
find documentation with more examples following those links.
- For an argument with a name you define
NamedArg
using a combination ofshort
,long
andenv
. At the same time you can attachhelp
. NamedArg::switch
- simple switch that returnstrue
if it’s present on a command line andfalse
otherwise.NamedArg::flag
- a variant ofswitch
that lets you return one of two custom values, for exampleColor::On
andColor::Off
.NamedArg::req_flag
- a variant ofswitch
that only only succeeds when it’s name is present on a command lineNamedArg::argument
- named argument containing a value, you can further customize it withadjacent
positional
- positional argument, you can further customize it withstrict
OptionParser::command
- subcommand parser.any
and its specialized versionliteral
are escape hatches that can parse anything not fitting into usual classification.pure
andpure_with
- a way to generate a value that can be composed without parsing it from the command line.
§Transforming and changing parsers
By default primitive parsers gives you back a single bool
, a single PathBuf
or a single
value produced by FromStr
trait, etc. You can further transform it by chaining methods from
Parser
trait, some of those methods are applied automagically if you are using derive API.
bpaf
distinguishes two types of parse failures - “value is absent” and
“value is present but invalid”, most parsers listed in this section only handle the first
type of failure by default, but you can use their respective catch
method to handle the later
one.
fallback
andfallback_with
- return a different value if parser fails to find what it is looking for. Generated help for former can be updated to include default value usingdisplay_fallback
anddebug_fallback
.optional
- returnNone
if value is missing instead of failing, see alsocatch
.many
,some
andcollect
- collect multiple values into a collection, usually a vector, see their respectivecatch
,catch
andcatch
.map
,parse
andguard
- transform and/or validate value produced by a parserto_options
- finalize the parser and prepare to run it
§Combining multiple parsers together
Once you have parsers for all the primitive fields figured out you can start combining them
together to produce a parser for a final result - data type you designed in the step one.
For derive API you apply annotations to data types with #[derive(Bpaf)
] and #[bpaf(..)]
,
with combinatoric API you use construct!
macro.
All fields in a struct needs to be successfully parsed in order for the parser to succeed and only one variant from enum will consume its values at a time.
You can use adjacent
annotation to parse multiple flags as an adjacent
group allowing for more unusual scenarios such as multiple value arguments or chained commands.
§Improving user experience
bpaf
would use doc comments on fields and structures in derive mode and and values passed
in various help
methods to generate --help
documentation, you can further improve it
using those methods:
hide_usage
andhide
- hide the parser from generated Usage line or whole generated helpgroup_help
andwith_group_help
- add a common description shared by several parserscustom_usage
- customize usage for a primitive or composite parserusage
andwith_usage
lets you to customize whole usage line as a whole either by completely overriding it or by building around it.
By default with completion enabled bpaf
would complete names for flags, arguments and
commands. You can also generate completion for argument values, possible positionals, etc.
This requires enabling autocomplete cargo feature.
And finally you can generate documentation for command line in markdown, html and manpage
formats using render_markdown
,
render_html
and render_manpage
,
for more detailed info see doc
module
§Testing your parsers and running them
- You can
OptionParser::run
the parser on the arguments passed on the command line check_invariants
checks for a few invariants in the parserbpaf
relies onrun_inner
runs the parser with customArgs
you can create either explicitly or implicitly using one of theFrom
implementations,Args
can be customized withset_comp
andset_name
.ParseFailure
contains the parse outcome, you can consume it either by hands or using one ofexit_code
,unwrap_stdout
andunwrap_stderr
§Cargo features
-
derive
: adds a dependency onbpaf_derive
crate and reexportBpaf
derive macro. You need to enable it to use derive API. Disabled by default. -
batteries
: helpers implemented with publicbpaf
API. Disabled by default. -
autocomplete
: enables support for shell autocompletion. Disabled by default. -
bright-color
,dull-color
: use more colors when printing--help
and such. Enabling either color feature adds some extra dependencies and might raise MRSV. If you are planning to use this feature in a published app - it’s best to expose them as feature flags:[features] bright-color = ["bpaf/bright-color"] dull-color = ["bpaf/dull-color"]
Disabled by default.
-
docgen
: generate documentation from help declaration, seeOptionParser::render_markdown
anddoc
. Disabled by default.
Modules§
- _documentation
extradocs
Project documentation - batteries
batteries
Batteries included - helpful parsers that use only public API - Documentation generation system
- Tools to define primitive parsers
- This module exposes parsers that accept further configuration with builder pattern
Macros§
- Compose several parsers to produce a single result
Structs§
- All currently present command line parameters with some extra metainfo
- String with styled segments.
- Ready to run
Parser
with additional information attached
Enums§
- Unsuccessful command line parsing outcome, use it for unit tests
- Shell
Comp autocomplete
Shell specific completion
Traits§
- Simple or composed argument parser
Functions§
- Parse a single arbitrary item from a command line
- Choose between several parsers specified at runtime
- Parse an environment variable
- Fail with a fixed error message
- A specialized version of
any
that consumes an arbitrary string - Parse a positional argument
- Parser that produces a fixed value
- Wrap a calculated value into a
Parser
Derive Macros§
- Bpaf
bpaf_derive
Derive macro for bpaf command line parser